/***
 * 
 *  ASMEX by RiskCare Ltd.
 * 
 * This source is copyright (C) 2002 RiskCare Ltd. All rights reserved.
 * 
 * Disclaimer:
 * This code is provided 'as is', with absolutely no warranty expressed or
 * implied.  Any use of this code is at your own risk.
 *   
 * You are hereby granted the right to redistribute this source unmodified
 * in its original archive. 
 * You are hereby granted the right to use this code, or code based on it,
 * provided that you acknowledge RiskCare Ltd somewhere in the documentation
 * of your application. 
 * You are hereby granted the right to distribute changes to this source, 
 * provided that:
 * 
 * 1 -- This copyright notice is retained unchanged 
 * 2 -- Your changes are clearly marked 
 * 
 * Enjoy!
 * 
 * --------------------------------------------------------------------
 * 
 * If you use this code or have comments on it, please mail me at 
 * support@jbrowse.com or ben.peterson@riskcare.com
 * 
 */

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.Win32;


namespace Asmex
{

	/// <summary>
	/// Encapsulates all the data needed for a find operation.
	/// Also contains the logic for iterating through a tree of BaseNodes and matching a node
	/// What we are looking for affects what nodes we recurse into
	/// </summary>
	internal class FindState
	{
		string _str;
		bool _findTypes;
		bool _findMethods;
		bool _findParameters;
		bool _findFields;
		bool _findResources;
		bool _findProperties;
		bool _findEvents;

		bool _startRoot;
		bool _caseful;
		bool _wholeWord;
		BaseNode _found;
		public FindState(){}

		//You can't match a constructor as it has no name.
		public bool Match(BaseNode node)
		{
			if (node is ModuleNode || node is TableNode || node is RowNode || node is ObjNode ||
				node is FileNode || node is FileRegionNode || node is FolderNode || node is AsmNode || 
				node is AsmRefNode || node is RelationshipNode || node is ConsNode)
				return false;

			if (node is TypeNode && !_findTypes)
				return false;
			if (node is NamespaceNode && !_findTypes)
				return false;
			if (node is MethodNode && !_findMethods)
				return false;
			if (node is ParamNode && !_findParameters)
				return false;
			if (node is FieldNode && !_findFields)
				return false;
			if (node is EventNode && !_findEvents)
				return false;
			if ((node is ResNode || node is ManResNode) && !_findResources)
				return false;
			if (node is PropNode && !_findProperties)
				return false;

			string a, b;
			a = _str;
			b = node.MatchingString;

			if (!_caseful)
			{
				a = a.ToLower();
				b = b.ToLower();
			}

			if (_wholeWord)
			{
				return a == b;
			}

			return (b.IndexOf(a) != -1);
		}

		public string String{get{return _str;} set{_str=value;}}
		public bool FindTypes{get{return _findTypes;} set{_findTypes=value;}}
		public bool FindParameters{get{return _findParameters;} set{_findParameters=value;}}
		public bool FindMethods{get{return _findMethods;} set{_findMethods=value;}}
		public bool FindFields{get{return _findFields;} set{_findFields=value;}}
		public bool FindResources{get{return _findResources;} set{_findResources=value;}}
		public bool FindProperties{get{return _findProperties;} set{_findProperties=value;}}
		public bool FindEvents{get{return _findEvents;} set{_findEvents=value;}}

		public bool WholeWord{get{return _wholeWord;} set{_wholeWord=value;}}
		public bool StartAtRoot{get{return _startRoot;} set{_startRoot=value;}}
		public bool Caseful{get{return _caseful;} set{_caseful=value;}}
		public BaseNode Node{get{return _found;} set{_found=value;}}

		//this actually indicates whether we need to check subnodes -- foldernodes need not have 'generatechildren'
		//called but their children are still checked.
		public bool NeedToExpandNode(BaseNode node)
		{
			if (node is AsmNode || node is NamespaceNode) return true;

			if (node is ModuleNode || node is FileRegionNode || node is TableNode || node is ErrorNode || 
				node is ObjNode || node is AsmRefNode || node is RelationshipNode) return false;


			if (node is FolderNode && node.Parent is AsmNode) return true;

			if (_findProperties || _findEvents || _findFields || _findMethods || _findParameters)
			{
				if (node is TypeNode) return true;
				if (node is FolderNode && node.Parent is TypeNode) return true;
			}

			if (_findParameters)
			{
				if (node is MethodNode || node is ConsNode) return true;
				if (node is FolderNode && (node.Parent is MethodNode || node.Parent is ConsNode) && node.Text.StartsWith("Param")) return true;
			}

			if (_findResources)
			{
				if (node is ManResNode) return true;
			}

			return false;
		}
	}

	/// <summary>
	/// The main frame.  Contains some mdi children and a docked ObjViewer.
	/// </summary>
	public class MainFrame : System.Windows.Forms.Form
	{
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem mnuFileOpen;
		private System.Windows.Forms.OpenFileDialog openFileDialog1;
		private System.Windows.Forms.MenuItem mnuAsmOpen;
		
		private System.Windows.Forms.ToolBar toolBar1;
		private System.ComponentModel.IContainer components;

		public static System.Windows.Forms.ImageList ilObjTree;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.Splitter splitter1;
		internal Asmex.ObjViewer.ObjViewer theViewer;
		private System.Windows.Forms.MenuItem menuItem4;
		private System.Windows.Forms.ImageList ilToolbar;

		public enum StartUpAction{Blank, Restore, Path, Common};

		private StartUpAction _startUpAction;
		private string[] _path;
		private System.Windows.Forms.MenuItem menuItem5;
		private System.Windows.Forms.MenuItem menuItem6;
		private System.Windows.Forms.MenuItem menuItem7;
		private System.Windows.Forms.MenuItem menuItem8;
		private System.Windows.Forms.MenuItem menuItem9;
		private System.Windows.Forms.MenuItem menuItem10;
		private System.Windows.Forms.MenuItem menuItem11;

		FindState _find;

		public StartUpAction SUA
		{
			get{return _startUpAction;}
			set{_startUpAction = value;}
		}

		public string[] Path
		{
			get{return _path;}
			set{_path = value;}
		}

		public MainFrame()
		{
			if (ilObjTree == null)
				ilObjTree = LoadImageListStream(this.GetType(), "Asmex.treeicons.bmp",new Size(16,16), true, new Point(0,0));

			
			InitializeComponent();

			//set the icon -- if we let studio write this code it freaks
			try
			{
				System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(AboutDlg));
				this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			}
			catch(Exception e)
			{
				//paranoia, it's the hardest song in original DDR.
			}
			

			ilToolbar = LoadImageListStream(this.GetType(), "Asmex.buttons.bmp", new Size(32,32), true, new Point(0,0));

			toolBar1.ImageList = ilToolbar;

			ToolBarButton btn;

			btn = new ToolBarButton();
			btn.ToolTipText = "Open File";
			btn.ImageIndex = 0;
			toolBar1.Buttons.Add(btn);

			btn = new ToolBarButton();
			btn.ToolTipText = "Open Assembly";
			btn.ImageIndex = 1;
			toolBar1.Buttons.Add(btn);

			btn = new ToolBarButton();
			btn.ToolTipText = "New View";
			btn.ImageIndex = 2;
			toolBar1.Buttons.Add(btn);

			btn = new ToolBarButton();
			btn.ToolTipText = "Find";
			btn.ImageIndex = 3;
			toolBar1.Buttons.Add(btn);

			btn = new ToolBarButton();
			btn.ToolTipText = "Find Again";
			btn.ImageIndex = 4;
			toolBar1.Buttons.Add(btn);

			btn = new ToolBarButton();
			btn.ToolTipText = "Preferences";
			btn.ImageIndex = 5;
			toolBar1.Buttons.Add(btn);
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.mnuFileOpen = new System.Windows.Forms.MenuItem();
			this.mnuAsmOpen = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItem8 = new System.Windows.Forms.MenuItem();
			this.menuItem5 = new System.Windows.Forms.MenuItem();
			this.menuItem6 = new System.Windows.Forms.MenuItem();
			this.menuItem7 = new System.Windows.Forms.MenuItem();
			this.menuItem4 = new System.Windows.Forms.MenuItem();
			this.menuItem9 = new System.Windows.Forms.MenuItem();
			this.menuItem10 = new System.Windows.Forms.MenuItem();
			this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
			this.toolBar1 = new System.Windows.Forms.ToolBar();
			this.ilToolbar = new System.Windows.Forms.ImageList(this.components);
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.theViewer = new Asmex.ObjViewer.ObjViewer();
			this.menuItem11 = new System.Windows.Forms.MenuItem();
			this.SuspendLayout();
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem1,
																					  this.menuItem5,
																					  this.menuItem9});
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.mnuFileOpen,
																					  this.mnuAsmOpen,
																					  this.menuItem2,
																					  this.menuItem3,
																					  this.menuItem8});
			this.menuItem1.Text = "&File";
			// 
			// mnuFileOpen
			// 
			this.mnuFileOpen.Index = 0;
			this.mnuFileOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
			this.mnuFileOpen.Text = "&Open File";
			this.mnuFileOpen.Click += new System.EventHandler(this.mnuFileOpen_Click);
			// 
			// mnuAsmOpen
			// 
			this.mnuAsmOpen.Index = 1;
			this.mnuAsmOpen.Shortcut = System.Windows.Forms.Shortcut.CtrlA;
			this.mnuAsmOpen.Text = "Open &Assembly";
			this.mnuAsmOpen.Click += new System.EventHandler(this.mnuAsmOpen_Click);
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 2;
			this.menuItem2.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftO;
			this.menuItem2.Text = "&Open File In New View";
			this.menuItem2.Click += new System.EventHandler(this.mnuFileOpenNV_Click);
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 3;
			this.menuItem3.Shortcut = System.Windows.Forms.Shortcut.CtrlShiftA;
			this.menuItem3.Text = "Open &Assembly In New View";
			this.menuItem3.Click += new System.EventHandler(this.mnuAsmOpenNV_Click);
			// 
			// menuItem8
			// 
			this.menuItem8.Index = 4;
			this.menuItem8.Shortcut = System.Windows.Forms.Shortcut.CtrlN;
			this.menuItem8.Text = "Create &New Blank View";
			this.menuItem8.Click += new System.EventHandler(this.mnuNewView_Click);
			// 
			// menuItem5
			// 
			this.menuItem5.Index = 1;
			this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem6,
																					  this.menuItem7,
																					  this.menuItem4});
			this.menuItem5.Text = "&Edit";
			// 
			// menuItem6
			// 
			this.menuItem6.Index = 0;
			this.menuItem6.Shortcut = System.Windows.Forms.Shortcut.CtrlF;
			this.menuItem6.Text = "&Find...";
			// 
			// menuItem7
			// 
			this.menuItem7.Index = 1;
			this.menuItem7.Shortcut = System.Windows.Forms.Shortcut.F3;
			this.menuItem7.Text = "Find &Again";
			// 
			// menuItem4
			// 
			this.menuItem4.Index = 2;
			this.menuItem4.Text = "&Preferences...";
			this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);
			// 
			// menuItem9
			// 
			this.menuItem9.Index = 2;
			this.menuItem9.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem11,
																					  this.menuItem10});
			this.menuItem9.Text = "&Help";
			// 
			// menuItem10
			// 
			this.menuItem10.Index = 1;
			this.menuItem10.Text = "&About...";
			this.menuItem10.Click += new System.EventHandler(this.mnuAbout_Click);
			// 
			// toolBar1
			// 
			this.toolBar1.Appearance = System.Windows.Forms.ToolBarAppearance.Flat;
			this.toolBar1.DropDownArrows = true;
			this.toolBar1.ImageList = this.ilToolbar;
			this.toolBar1.Name = "toolBar1";
			this.toolBar1.ShowToolTips = true;
			this.toolBar1.Size = new System.Drawing.Size(632, 39);
			this.toolBar1.TabIndex = 1;
			this.toolBar1.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.OnToolBar);
			// 
			// ilToolbar
			// 
			this.ilToolbar.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
			this.ilToolbar.ImageSize = new System.Drawing.Size(16, 16);
			this.ilToolbar.TransparentColor = System.Drawing.Color.Transparent;
			// 
			// splitter1
			// 
			this.splitter1.Dock = System.Windows.Forms.DockStyle.Right;
			this.splitter1.Location = new System.Drawing.Point(333, 39);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(3, 602);
			this.splitter1.TabIndex = 3;
			this.splitter1.TabStop = false;
			// 
			// theViewer
			// 
			this.theViewer.Dock = System.Windows.Forms.DockStyle.Right;
			this.theViewer.Location = new System.Drawing.Point(336, 39);
			this.theViewer.Name = "theViewer";
			this.theViewer.Size = new System.Drawing.Size(296, 602);
			this.theViewer.TabIndex = 4;
			// 
			// menuItem11
			// 
			this.menuItem11.Index = 0;
			this.menuItem11.Text = "&Hints...";
			this.menuItem11.Click += new System.EventHandler(this.menuItem11_Click);
			// 
			// MainFrame
			// 
			this.AllowDrop = true;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(632, 641);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.splitter1,
																		  this.theViewer,
																		  this.toolBar1});
			this.IsMdiContainer = true;
			this.Menu = this.mainMenu1;
			this.Name = "MainFrame";
			this.Text = "Assembly Viewer";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.MainFrame_Closing);
			this.MdiChildActivate += new System.EventHandler(this.OnMdiChildActivate);
			this.Load += new System.EventHandler(this.MainFrame_Load);
			this.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDrop);
			this.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		public static void Main() 
		{
			Application.Run(new MainFrame());
		}

		private void mnuAsmOpen_Click(object sender, System.EventArgs e)
		{
			GACPicker p = new GACPicker();
			if (p.ShowDialog() == DialogResult.OK)
			{
				AsmView asm = GetView(false);
				asm.AddRoot(BaseNode.MakeNode(p.Assembly));
			}
		}

		private void mnuFileOpen_Click(object sender, System.EventArgs e)
		{
			openFileDialog1.CheckFileExists= true;
			openFileDialog1.CheckPathExists = true;
			openFileDialog1.Filter ="Exe files (*.exe)|*.exe|Dll files (*.dll)|*.dll|All files (*.*)|*.*";
			openFileDialog1.Multiselect = false;
			openFileDialog1.ReadOnlyChecked = true;
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
			{
				AsmView asm = GetView(false);
				asm.AddRoot(BaseNode.MakeNode(openFileDialog1.FileName));
			}
		}

		private void mnuAsmOpenNV_Click(object sender, System.EventArgs e)
		{
			GACPicker p = new GACPicker();
			if (p.ShowDialog() == DialogResult.OK)
			{
				AsmView asm = GetView(true);
				asm.AddRoot(BaseNode.MakeNode(p.Assembly));
			}
		}

		private void mnuFileOpenNV_Click(object sender, System.EventArgs e)
		{
			openFileDialog1.CheckFileExists= true;
			openFileDialog1.CheckPathExists = true;
			openFileDialog1.Filter ="Exe files (*.exe)|*.exe|Dll files (*.dll)|*.dll|All files (*.*)|*.*";
			openFileDialog1.Multiselect = false;
			openFileDialog1.ReadOnlyChecked = true;
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
			{
				AsmView asm = GetView(true);
				asm.AddRoot(BaseNode.MakeNode(openFileDialog1.FileName));
			}
		}

		private void mnuFind_Click(object sender, System.EventArgs e)
		{
			FindDialog dlg = new FindDialog(_find);

			if (dlg.ShowDialog() == DialogResult.OK)
			{
				_find = dlg.Find;
				_find.Node = ((AsmView)ActiveMdiChild).SelectedNode;
				((AsmView)ActiveMdiChild).Find(_find);
			}
		}

		private void mnuFindAgain_Click(object sender, System.EventArgs e)
		{
			if (_find != null)
			{
				_find.Node = ((AsmView)ActiveMdiChild).SelectedNode;
				_find.StartAtRoot = false;
				((AsmView)ActiveMdiChild).Find(_find);
			}
		}

		private void mnuNewView_Click(object sender, System.EventArgs e)
		{
			GetView(true);
		}

		private AsmView GetView(bool bNew)
		{
			AsmView v;
			if (bNew)
			{
				v = new AsmView();
			}
			else
			{
				v = (AsmView)this.ActiveMdiChild;
				if (v==null) v = new AsmView();
			}
			v.MdiParent = this;
			v.Visible = true;
			return v;
		}

		private void MainFrame_Load(object sender, System.EventArgs e)
		{
			AsmView asm;

			LoadPrefs();

			switch(_startUpAction)
			{
				case StartUpAction.Restore:
					LoadState();break;
				case StartUpAction.Blank:
					break;
				case StartUpAction.Common:
					asm = GetView(true);
					asm.WindowState = FormWindowState.Maximized;
					asm.AddRoot(new AsmNode(typeof(System.String).Assembly));
					asm.AddRoot(new AsmNode(typeof(System.Windows.Forms.Form).Assembly));
					asm.AddRoot(new AsmNode(typeof(System.Xml.XmlAttribute).Assembly));
					asm.AddRoot(new AsmNode(typeof(System.Web.Services.WebService).Assembly));
					asm.AddRoot(new AsmNode(typeof(System.Drawing.Brushes).Assembly));
					break;
				default:
					asm = GetView(true);
					asm.WindowState = FormWindowState.Maximized;
					IList ass = GetPathAssemblies();
					for (int i=0; i< ass.Count; ++i)
					{
						asm.AddRoot(new AsmNode((Assembly)ass[i]));
					}	
					break;
			}
			
		}


		public static ImageList LoadImageListStream(Type assemblyType, 
			string imageName, 
			Size imageSize,
			bool makeTransparent,
			Point transparentPixel)
		{
			// Create storage for bitmap strip
			ImageList images = new ImageList();

			// Define the size of images we supply
			images.ImageSize = imageSize;

			// Get the assembly that contains the bitmap resource
			Assembly myAssembly = Assembly.GetAssembly(assemblyType);

			// Get the resource stream containing the images
			Stream imageStream = myAssembly.GetManifestResourceStream(imageName);

			// Load the bitmap strip from resource
			Bitmap pics = new Bitmap(imageStream, true);

			if (makeTransparent)
			{
				Color backColor = pics.GetPixel(transparentPixel.X, transparentPixel.Y);
    
				// Make backColor transparent for Bitmap
				pics.MakeTransparent(backColor);
			}
			    
			// Load them all !
			images.Images.AddStrip(pics);

			return images;
		}

		private void OnToolBar(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
		{
			if (e.Button.ToolTipText == "Open File")
			{
				mnuFileOpen_Click(sender, e);
			}
			else if (e.Button.ToolTipText == "Open Assembly")
			{
				mnuAsmOpen_Click(sender, e);
			}
			else if (e.Button.ToolTipText == "New View")
			{
				mnuNewView_Click(sender, e);
			}
			else if (e.Button.ToolTipText == "Find")
			{
				mnuFind_Click(sender, e);
			}
			else if (e.Button.ToolTipText == "Find Again")
			{
				mnuFindAgain_Click(sender, e);
			}
			else if (e.Button.ToolTipText == "Preferences")
			{
				menuItem4_Click(sender, e);
			}
		}

		private void MainFrame_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			try
			{

				RegistryKey rk = Registry.LocalMachine.CreateSubKey("SOFTWARE\\jBrowse\\Asmex");
				rk.DeleteSubKeyTree("");
			}
			catch(Exception ee)
			{
			}

			SaveState();
			SavePrefs();
		}

		private void OnMdiChildActivate(object sender, System.EventArgs e)
		{
			if (ActiveMdiChild == null) return;

			((AsmView)ActiveMdiChild).OnActivate();
		}

		private void OnDrop(object sender, System.Windows.Forms.DragEventArgs e)
		{
			object o  = e.Data.GetData(DataFormats.FileDrop);
			if (o == null)
			{
				MessageBox.Show("Drag a file from Explorer to open it");
				return;
			}

			AsmView v = GetView(true);
			Array a = (Array)o;

			for(int i=0;i<a.Length;++i)
			{
				BaseNode b = BaseNode.MakeNode(a.GetValue(i));
				if (b != null)
					v.AddRoot(b);
			}

		}

		private void OnDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
		{
			object o  = e.Data.GetData(DataFormats.FileDrop);
			if (o==null)
			{
				e.Effect = DragDropEffects.None;
			}
			else
			{
				e.Effect = DragDropEffects.Copy;
			}
		}

		private void menuItem4_Click(object sender, System.EventArgs e)
		{
			ConfigDlg dlg = new ConfigDlg(this);
			dlg.ShowDialog();
		}	
	

		void SaveState()
		{
			try
			{
				RegistryKey rk = Registry.CurrentUser.CreateSubKey("SOFTWARE\\jBrowse\\Asmex");

				for (int i=0; i < this.MdiChildren.Length; ++i)
				{
					AsmView v = (AsmView)MdiChildren[i];

					RegistryKey vk = rk.CreateSubKey(i.ToString());

					vk.SetValue("x", v.Left);
					vk.SetValue("y", v.Top);
					vk.SetValue("w", v.Width);
					vk.SetValue("h", v.Height);
					vk.SetValue("s", (int)v.WindowState);

					for(int j=0; j < v.Roots.Length; ++j)
					{
						vk.SetValue("root" + j.ToString(), v.Roots[j].Desc);
					}

					vk.Close();
				}	

				rk.Close();
			}
			catch(Exception e)
			{
				MessageBox.Show("Unable to save configuration; does this account have permission to write to HKEY_LOCAL_MACHINE\\Software?");
			}
		}

		void LoadState()
		{
			try
			{
				RegistryKey rk = Registry.LocalMachine.CreateSubKey("SOFTWARE\\jBrowse\\Asmex");

				string[] subkeys = rk.GetSubKeyNames();
				for (int i=0; i < subkeys.Length; ++i)
				{
					AsmView v = GetView(true);

					RegistryKey vk = rk.OpenSubKey(subkeys[i]);

					v.WindowState = (FormWindowState)vk.GetValue("s", FormWindowState.Normal);
					v.Left = (int)vk.GetValue("x", 100);
					v.Top = (int)vk.GetValue("y", 100);
					v.Width = (int)vk.GetValue("w", 600);
					v.Height = (int)vk.GetValue("h", 400);
					

					string[] values = vk.GetValueNames();
					for(int j=0; j < values.Length; ++j)
					{
						if (values[j].StartsWith("root"))
							v.AddRoot(BaseNode.MakeNode((string)vk.GetValue(values[j])));
					}

					vk.Close();
				}	

				rk.Close();
			}
			catch(Exception e)
			{
				MessageBox.Show("Unable to load configuration; does this account have permission to access to HKEY_LOCAL_MACHINE\\Software?");
			}

		}

		void SavePrefs()
		{
			try
			{
				RegistryKey rk = Registry.LocalMachine.CreateSubKey("SOFTWARE\\jBrowse\\Asmex");

				rk.SetValue("x", Left);
				rk.SetValue("y", Top);
				rk.SetValue("w", Width);
				rk.SetValue("h", Height);
				rk.SetValue("s", theViewer.Width);

				rk.SetValue("saa", (int)_startUpAction);
				rk.SetValue("path", _path);
			}
			catch(Exception e)
			{
			}
		}

		void LoadPrefs()
		{
			try
			{
				RegistryKey rk = Registry.LocalMachine.CreateSubKey("SOFTWARE\\jBrowse\\Asmex");
				
				Left = (int)rk.GetValue("x", 100);
				Top = (int)rk.GetValue("y", 100);
				Width = (int)rk.GetValue("w", 600);
				Height = (int)rk.GetValue("h", 400);
				theViewer.Width = (int)rk.GetValue("s", 400);

				_startUpAction = (StartUpAction)(int)rk.GetValue("saa", (int)StartUpAction.Restore);
				_path = (string[])rk.GetValue("path", new string[]{});
			}
			catch(Exception e)
			{
			}
		}

		public ArrayList GetPathAssemblies()
		{
			ArrayList arr = new ArrayList();

			for(int i=0; i < _path.Length; ++i)
			{
				GetDirAssemblies(_path[i], arr);
			}

			return arr;
		}

		void GetDirAssemblies(string dir, ArrayList a)
		{
			Assembly asm;
			string[] files = Directory.GetFiles(dir);

			for(int i=0;i<files.Length;++i)
			{
				asm = null;

				try
				{
					asm = Assembly.LoadFrom(files[i]);
				}
				catch(Exception e){}
				
				if (asm != null)
				{
					a.Add(asm);
				}
			}

			string[] dirs = Directory.GetDirectories(dir);

			for(int i=0; i< dirs.Length;++i)
			{
				GetDirAssemblies(dirs[i], a);
			}


		}

		private void mnuAbout_Click(object sender, System.EventArgs e)
		{
			new AboutDlg().Show();
		}

		private void menuItem11_Click(object sender, System.EventArgs e)
		{
			new HintDlg().Show();
		}


		
	}
}
